

namespace Stee.CAP8.MessageBus.Interface.Models
{
    using System;

    /// <summary>
    /// Message topic containing name, key and message type
    /// </summary>
    public class TopicName : IEquatable<TopicName>
    {
        /// <summary>
        /// Gets the subscription topic reference of event / command / generic name
        /// </summary>
        public string Name { get; }

        /// <summary>
        /// Gets the unique identifier within the topic / matching pattern for routing messages into respective queues
        /// </summary>
        public string Route { get; }

        /// <summary>
        /// Gets the class validity
        /// </summary>
        public bool IsValid
        {
            get { return this.Validate(); }
        }


        #region Constructor

        /// <summary>
        /// Initializes a new instance of the TopicMessage class
        /// </summary>
        /// <param name="name">Name of event or command / generic name for topic subscription reference</param>
        /// <param name="route">Unique identifier within the topic / matching pattern for routing messages into respective queues.
        /// Eg.: "product_type" / "product.kitchen.utensils" / "product.kitchen.*"</param>
        public TopicName(string name, string route)
        {
            name = name?.Trim();

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            this.Name = name;
            this.Route = route;
        }

        #endregion Constructor


        #region Public Methods

        /// <summary>
        /// Compare equality method
        /// </summary>
        /// <param name="other">Other TopicName instance</param>
        /// <returns>Return TRUE if other instance is identical else FALSE</returns>
        public bool Equals(TopicName other)
        {
            return this.Equals((object)other);
        }

        /// <summary>
        /// Overridden Equals method
        /// </summary>
        /// <param name="other">Other TopicName instance</param>
        /// <returns>Return TRUE if other instance is identical else FALSE</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            else
            {
                return (obj is TopicName) ?
                    string.Equals(this.ToString(), obj.ToString(), StringComparison.InvariantCultureIgnoreCase) : false;
            }
        }

        /// <summary>
        /// Overridden GetHashCode method
        /// </summary>
        /// <returns>Return the hash code</returns>
        public override int GetHashCode()
        {
            return this.Name.GetHashCode(StringComparison.InvariantCultureIgnoreCase) ^
                this.Route.GetHashCode(StringComparison.InvariantCultureIgnoreCase);
        }

        /// <summary>
        /// Overridden ToString method
        /// </summary>
        /// <returns>Return the stringified object</returns>
        public override string ToString()
        {
            return $"{this.Name}_{this.Route}";
        }

        #endregion Public Methods


        #region Private Methods

        /// <summary>
        /// Validate class
        /// </summary>
        /// <returns>Return TRUE if valid else FALSE</returns>
        private bool Validate()
        {
            return !string.IsNullOrEmpty(this.Name);
        }

        #endregion Private Methods
    }
}
